﻿namespace SP2010.Enhancements.SEO
{   
    using System;
    using System.IO;
    using System.Runtime.CompilerServices;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Web;
    using Microsoft.Security.Application;

    internal class HtmlPurifier : Stream
    {
        private Stream _originalFilter;

        public HtmlPurifier(Stream originalFilter)
        {
            try
            {
                this._originalFilter = originalFilter;
            }
            catch
            {
                throw;
            }
        }

        public override void Close()
        {
            try
            {
                this._originalFilter.Close();
            }
            catch
            {
                throw;
            }
        }

        public override void Flush()
        {
            try
            {
                this._originalFilter.Flush();
            }
            catch
            {
                throw;
            }
        }

        private string getEncodedHTML(string html)
        {
            string str;
            try
            {
                StringBuilder builder = new StringBuilder(HttpUtility.HtmlEncode(html));
                builder = new StringBuilder(Regex.Replace(builder.Replace("&lt;b&gt;", "<b>").Replace("&lt;/b&gt;", "</b>").Replace("&lt;strong&gt;", "<strong>").Replace("&lt;/strong&gt;", "</strong>").Replace("&lt;i&gt;", "<i>").Replace("&lt;/i&gt;", "</i>").Replace("&lt;em&gt;", "<em>").Replace("&lt;/em&gt;", "</em>").Replace("&lt;u&gt;", "<u>").Replace("&lt;/u&gt;", "</u>").Replace("&lt;hr /&gt;", "<hr />").Replace("&lt;br&gt;", "<br />").Replace("&lt;br/&gt;", "<br />").Replace("&lt;br /&gt;", "<br />").ToString(), "&lt;img(.*?)/&gt;", "<img$1/>", RegexOptions.IgnoreCase));
                builder = new StringBuilder(Regex.Replace(builder.ToString(), "&lt;(div|span|table|tbody|thead|tr|th|td|font|ol|ul|li|a|p)(.*?)&gt;", "<$1$2>", RegexOptions.IgnoreCase));
                builder = new StringBuilder(Regex.Replace(builder.ToString(), "&lt;/(div|span|table|tbody|thead|tr|th|td|font|ol|ul|li|a|p)&gt;", "</$1>", RegexOptions.IgnoreCase));
                builder = new StringBuilder(Regex.Replace(builder.ToString(), "&lt;!--(.*?)--&gt;", ""));
                str = builder.Replace("&quot;", "\"").Replace("&amp;", "&").ToString();
            }
            catch
            {
                throw;
            }
            return str;
        }

        private string getSafeHTML(string html)
        {
            string str;
            try
            {
                html = Sanitizer.GetSafeHtml(html);
                str = html;
            }
            catch
            {
                throw;
            }
            return str;
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            int num;
            try
            {
                num = this._originalFilter.Read(buffer, offset, count);
            }
            catch
            {
                throw;
            }
            return num;
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            long num;
            try
            {
                num = this._originalFilter.Seek(offset, origin);
            }
            catch
            {
                throw;
            }
            return num;
        }

        public override void SetLength(long value)
        {
            try
            {
                this._originalFilter.SetLength(value);
            }
            catch
            {
                throw;
            }
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            byte[] dst = new byte[count];
            Buffer.BlockCopy(buffer, offset, dst, 0, count);
            string html = Encoding.Default.GetString(buffer);
            html = this.getSafeHTML(html);
            html = this.getEncodedHTML(html);
            byte[] bytes = Encoding.Default.GetBytes(html);
            this._originalFilter.Write(bytes, 0, bytes.GetLength(0));
        }

        public override bool CanRead
        {
            get
            {
                return true;
            }
        }

        public override bool CanSeek
        {
            get
            {
                return true;
            }
        }

        public override bool CanWrite
        {
            get
            {
                return true;
            }
        }

        public override long Length
        {
            get
            {
                return 0L;
            }
        }

        public override long Position { get; set; }
    }
}

